package com.xinyue.auto.reader.process;

import java.util.List;

import org.dom4j.Element;

import com.xinyue.auto.annotation.SetBoolean;
import com.xinyue.auto.bean.Attribute;
import com.xinyue.auto.exception.PropertyException;
import com.xinyue.auto.reader.Process;
import com.xinyue.auto.reader.major.AttributeMajor;
import com.xinyue.auto.reader.util.ColumnUtil;
import com.xinyue.auto.reader.util.TemporalUtil;
import com.xinyue.auto.type.Type;
import com.xinyue.auto.util.ArrayUtil;
import com.xinyue.auto.util.StringUtil;

public class PropertyProcess extends AttributeMajor{
	public PropertyProcess(Process read) {
		super(read);
	}
	
	@SetBoolean(false)
	private boolean nfAtt;//非数据库字段类型
	private Attribute att;//属性数据封装对象
	
	@SuppressWarnings("unchecked")
	@Override
	protected void process() throws Exception {
		List<Element> props = xml.elements(property_);
		if(props == null || props.size() == 0) {
			throw new PropertyException("标签未定义", holder.getException());
		}
		
		for (Element prop: props) {
			att = new Attribute();
			
			try {
				//公共属性
				commonRead(prop);
			} catch (Exception e) {
				throw new PropertyException(e.getMessage(), holder.getException());
			}
			
			//装配数据
			att.setName(name);
			att.setType(type);
			att.setDesc(desc);
			att.setAnnotations(ArrayUtil.toArray(anns));
			
			//将数据对象添加至对象
			if(nfAtt) {
				holder.getEntity().getNfAtts().add(att);
			}else {
				holder.getEntity().getAtts().add(att);
			}
		}
	}

	/**
	 * 读取property标签上属性信息，并封装成JPA的注解类型
	 * @throws Exception 
	 */
	@Override
	protected void columnAnn(Element prop) throws Exception {
		StringBuilder column = new StringBuilder();//column数据
		
		//transient：是否瞬时字段
		String trans = prop.attributeValue(transient_);

		//当此属性是瞬时字段时，非数据库字段没有Column注解
		if(StringUtil.isNull(trans)) {
			String t_name = ColumnUtil.compoundByName(column, prop, t_name_);//name：字段名
			String length = ColumnUtil.compound(column, prop, length_);//长度
			String unique = ColumnUtil.compound(column, prop, unique_);//unique：是否唯一
			String nullable = ColumnUtil.compound(column, prop, nullable_);//nullable：是否可以为空
			String defin = ColumnUtil.compound4String(column, prop, columnDefinition_);//columnDefinition：自定义字段类型：需要数据库支持
			ColumnUtil.compound(column, prop, insertable_);//inserttable：新建表时是否可以新建数据
			ColumnUtil.compound(column, prop, updatable_);//updateable：更新时是否可以更新该列
			
			//t_name属性为空时，使用bean属性名作为数据库表字段名
			if(StringUtil.isNull(t_name)) {
				att.setDbName(name);
			}else {
				att.setDbName(t_name);
			}
			
			if(StringUtil.isNull(defin)) {
				att.setDbType(type);
			}else {
				att.setDbType(defin);
			}
			
			att.setLength(length);
			
			if(!StringUtil.isNull(unique)) {
				att.setUnique(Boolean.valueOf(unique));
			}
			if(!StringUtil.isNull(nullable)) {
				att.setNullable(Boolean.valueOf(nullable));
			}
			
			//日期格式化
			if(Type.DATE.equals(type)) {
				String temporal = prop.attributeValue(temporal_);
				if(TemporalUtil.validate(temporal)) {
					anns.add("@Temporal(TemporalType." + temporal + ")");
					holder.getBeanImpt().add("javax.persistence.Temporal");
					holder.getBeanImpt().add("javax.persistence.TemporalType");
				}
			}
		}else {
			//非数据库字段类型
			nfAtt = true;
			
			anns.add("@Transient");
			holder.getBeanImpt().add("javax.persistence.Transient");
		}
		
		//属性上的注解，当该属性不是瞬时字段时添加Column注解
		if(column.length() > 0) {
			String annc = "@Column(" + column.substring(2, column.length()) + ")";
			anns.add(annc);
			holder.getBeanImpt().add("javax.persistence.Column");
		}
	}
}